﻿using MeetSomeNearbyStrangerWebApi.ConfigurationSettings;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace MeetSomeNearbyStrangerWebApi.MessageHandlers
{
    public class BasicMessageHandler : DelegatingHandler
    {
        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            string logFileDirPath = Environment.ExpandEnvironmentVariables("%userprofile%") + @"\AppData\Local\MSNS\";

            if (!Directory.Exists(logFileDirPath))
            {
                Directory.CreateDirectory(logFileDirPath);
            }

            FileStream hlogFile = new FileStream(logFileDirPath + "MSNS.log", FileMode.OpenOrCreate, FileAccess.Write);
            TextWriterTraceListener myListener = new TextWriterTraceListener(hlogFile);
            Debug.Listeners.Clear();
            Debug.Listeners.Add(myListener);
            Debug.AutoFlush = true;

            string path = request.RequestUri.PathAndQuery;
            int apiEndingSlashIndex = path.IndexOf('/', 1);
            string api = path.Substring(1, apiEndingSlashIndex - 1);
            int controllerEndingSlashIndex = path.IndexOf('/', apiEndingSlashIndex + 1);
            string controller = path.Substring(apiEndingSlashIndex + 1, controllerEndingSlashIndex - apiEndingSlashIndex - 1);
            int actionEndingSymbolIndex = path.IndexOf('?', controllerEndingSlashIndex + 1);
            string action;
            if (actionEndingSymbolIndex == -1)
            {
                action = path.Substring(controllerEndingSlashIndex + 1);
            }
            else
            {
                action = path.Substring(controllerEndingSlashIndex + 1, actionEndingSymbolIndex - controllerEndingSlashIndex - 1);
            }

            Debug.WriteLine(string.Format("Api: {0}", api));
            Debug.WriteLine(string.Format("Controller: {0}", controller));
            Debug.WriteLine(string.Format("Action: {0}", action));

            HttpResponseMessage response = null;
            try
            {
                ControllerAction act = ControllerManager.FindActionPerController("users", action);
                Debug.WriteLine(request.Method.Method);
                string correctMethod = Enum.GetName(typeof(MeetSomeNearbyStrangerWebApi.ConfigurationSettings.HttpMethod), act.Type);
                if (correctMethod != request.Method.Method)
                {
                    response = new HttpResponseMessage(HttpStatusCode.MethodNotAllowed)
                    {
                        Content = new StringContent(string.Format("{0} method on resource '{1}' is not permitted. Try {2} instead.",
                            request.Method.Method, path, correctMethod))
                    };
                }
                else
                {
                    if (act.Name != UsersControllerActions.SendUserData)
                    {
                        if (!request.Headers.Contains("X-userID"))
                        {
                            response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
                            {
                                Content = new StringContent("The client is not authorized to request the resource. It must provide a security key.")
                            };
                        }
                    }
                }
            }
            catch (ArgumentException e)
            {
                response = new HttpResponseMessage(HttpStatusCode.NotFound)
                {
                    Content = new StringContent(e.Message)
                };
            }

            if (response == null)
            {
                response = await base.SendAsync(request, cancellationToken);
            }

            hlogFile.Close();
            hlogFile.Dispose();

            return response;
        }
    }
}